package ca.uvic.cs.cogz.util;

import java.awt.Dimension;
import java.awt.Point;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Properties;

import ca.uvic.cs.cogz.PromptUIPlugin;
import edu.stanford.smi.protegex.prompt.plugin.PluginManager;

public class PropertiesManager {
	/** enum for describing available repository dialog properties */
	public enum FileOpenDialogProperties {
		LAST_SOURCE_ONTOLOGY("LAST_SOURCE_ONTOLOGY"), LAST_TARGET_ONTOLOGY("LAST_TARGET_ONTOLOGY"), LAST_MAPPING_ONTOLOGY("LAST_MAPPING_ONTOLOGY");

		private String typeText;

		FileOpenDialogProperties(String typeText) {
			this.typeText = this.getClass().getCanonicalName() + "." + typeText;
		}

		public String toString() {
			return this.typeText;
		}
	}

	public enum MappingVisualizationProperties {
		VERTICAL_SPLIT_POSITION("Vertical Split Position"), SOURCE_SPLIT_POSITION("Source Split Position"), TARGET_SPLIT_POSITION("Target Split Position"), NUM_OF_RUNS("Number of runs"), NEVER_SHOW_SURVEY_AGAIN(
				"Never show again");

		private String typeText;

		MappingVisualizationProperties(String typeText) {
			this.typeText = this.getClass().getCanonicalName() + "." + typeText;
		}

		public String toString() {
			return this.typeText;
		}
	}

	private static final String PROPERTIES_FILE = PluginManager.getPromptPluginsDirectory() + PromptUIPlugin.class.getPackage().getName() + File.separatorChar + "cogzMapper";

	private static PropertiesManager propertiesManager = null;

	private Properties properties;

	private PropertiesManager() {
		properties = new Properties();

		if (new File(PROPERTIES_FILE).exists()) {
			// load properties from last invocation
			InputStream in;
			try {
				in = new FileInputStream(PROPERTIES_FILE);
				properties.load(in);
				in.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static PropertiesManager getInstance() {
		if (propertiesManager == null) {
			propertiesManager = new PropertiesManager();
		}
		return propertiesManager;
	}

	public void saveProperties() {
		FileOutputStream out;
		try {
			out = new FileOutputStream(PROPERTIES_FILE);
			properties.store(out, "---No Comment---");
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Gets the property associated with the given key and converts this value to a boolean.
	 * 
	 * @param key The key for this property value.
	 * @return The property value as an boolean, false if not found.
	 */
	public boolean getPropertyAsBoolean(Object key) {
		try {
			String property = getProperty(key);
			if (property != null) {
				return Boolean.parseBoolean(property);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * Gets the property associated with the given key and converts this value to an int.
	 * 
	 * @param key The key for this property value.
	 * @return The property value as an int, -1 if not found.
	 */
	public int getPropertyAsInt(Object key) {
		try {
			String property = getProperty(key);
			if (property != null) {
				return Integer.parseInt(property);
			}
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
		return -1;
	}

	/**
	 * Gets the property associated with the given key and converts this value to a Point object.
	 * 
	 * @param key The key for this property value.
	 * @return The property value as a Point object, null if not found.
	 */
	public Point getPropertyAsPoint(Object key) {
		try {
			String property = getProperty(key);
			if (property != null) {
				String[] coords = property.split(",");
				if (coords.length == 2) {
					Point location = new Point((int) Double.parseDouble(coords[0]), (int) Double.parseDouble(coords[1]));
					return location;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * Gets the property associated with the given key and converts this value to a Dimension
	 * object.
	 * 
	 * @param key The key for this property value.
	 * @return The property value as a Dimension object, null if not found.
	 */
	public Dimension getPropertyAsDimension(Object key) {
		try {
			String property = getProperty(key);
			if (property != null) {
				String[] dimensions = property.split(",");
				if (dimensions.length == 2) {
					Dimension size = new Dimension((int) Double.parseDouble(dimensions[0]), (int) Double.parseDouble(dimensions[1]));
					return size;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public String getProperty(Object key) {
		return properties.getProperty(key.toString());
	}

	/**
	 * Saves the Dimension object in the properties file.
	 * 
	 * @param key
	 * @param dimension
	 */
	public void setProperty(Object key, Dimension dimension) {
		String value = dimension.getWidth() + "," + dimension.getHeight();
		setProperty(key, value);
	}

	/**
	 * Saves the Point object in the properties file.
	 * 
	 * @param key
	 * @param point
	 */
	public void setProperty(Object key, Point point) {
		String value = point.getX() + "," + point.getY();
		setProperty(key, value);
	}

	/**
	 * Saves the given String value in the properties file.
	 * 
	 * @param key
	 * @param value
	 */
	public void setProperty(Object key, String value) {
		properties.setProperty(key.toString(), value);

		saveProperties();
	}

	public Properties getProperties() {
		return properties;
	}
}
